#pragma once
#include <iostream>
#include <unistd.h>
#include <string>
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include"InetAddr.hpp"
#include "log.hpp"
int gport =8888;
int gscd=-1;
int gblock=8;
using namespace log_ns;
enum
{
    SOCKET_ERROR = 1,
    BIND_ERROR,
    LISTEN_ERROR,
    ACCEPT_ERROR
};

class Tcp{
  public:
  Tcp(int port=gport)
  :
  _ls_scd(gscd),
  _port(port)
  {

  }

 void init(){
    _ls_scd=socket(AF_INET,SOCK_STREAM,0);
    if (_ls_scd < 0) {
        LOG(FATAL, "socket error\n");
        exit(SOCKET_ERROR);
    } else {
        LOG(DEBUG, "socket create success, _socketd: %d\n", _ls_scd);
    }
    struct sockaddr_in local;
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_port = htons(_port);
    local.sin_addr.s_addr = INADDR_ANY;
     int n = bind(_ls_scd, (struct sockaddr*)&local, sizeof(local));
    if (n < 0) {
        LOG(FATAL, "bind error\n");
        exit(BIND_ERROR);
    }
    LOG(DEBUG, "socket bind success\n");
    if(::listen(_ls_scd,gblock)<0){
        LOG(FATAL, "socket error\n");
        exit(LISTEN_ERROR);
    }
    else{
        LOG(DEBUG, "socket listen success\n");
    }
    }
 void loop(){
    while(true){
      struct sockaddr_in aim;
      socklen_t len = sizeof(aim);
      int sockted =::accept(_ls_scd,(sockaddr*)&aim,&len);
      if(sockted<0){
      LOG(WARNING, "accept error\n");
      continue;
      }
      InetAddr client(aim);
       LOG(DEBUG, "socket accept success\n");
       service(client,sockted);
    }
 }
    void service(InetAddr client, int sockted){
        while(true){
        char buff[1024];
        ssize_t n=::read(sockted,buff,sizeof(buff)-1);
        if(n>0){
         LOG(DEBUG, "socket read success\n");
        buff[n]=0;
        std::string mes="[client]:";
        mes+=buff;
       ssize_t n= write(sockted,mes.c_str(),mes.size());
        }
        else{
             LOG(DEBUG, "mes read wrong ip:: %s\n");
             break;
        }
        }
    }
 
  private:
  int _ls_scd;
  int _port;
};
